﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Qiang.Topology.Geometries;

namespace Qiang.QMath
{
    public class KdPoint : Coordinate, ICloneable
    {

        public KdPoint(int numDimensions)
            :base()
        {
            this._numDimensions = numDimensions;
        }

        public KdPoint(double[] coord)
        {
            this._numDimensions = coord.Length;

            if (this._numDimensions > 0) this.X = coord[0];
            if (this._numDimensions > 1) this.Y = coord[1];
            if (this._numDimensions > 2) this.Z = coord[2];
        }


        private readonly int _numDimensions;

        /// <summary>
        /// 其实就是维度
        /// </summary>
        public int NumDimensions
        {
            get { return _numDimensions; }
        } 

        

        public double this[int index]
        {
            get
            {
                switch (index)
                {
                    case 0:
                        return this.X;
                    case 1:
                        return this.Y;
                    case 2:
                        return this.Z;
                    default :
                        return double.NaN;
                }
            }
            set
            {
                switch (index)
                {
                    case 0:
                        this.X = value;
                        return ;
                    case 1:
                        this.Y = value;
                        return;
                    case 2:
                        this.Z = value;
                        return;
                    default :
                        return;
                }
            }
        }


        /// <summary>
        /// 判断两个点坐标是否相等
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            KdPoint objPt = obj as KdPoint;

            if (objPt == null)
            {
                return false;
            }

            if (double.IsNaN(this.Z) || double.IsNaN(objPt.Z)) return (this.X == objPt.X && this.Y == objPt.Y);

            return (this.X == objPt.X && this.Y == objPt.Y && this.Z == objPt.Z);

        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }


        /// <summary>
        /// 距离的平方
        /// </summary>
        /// <param name="pt1"></param>
        /// <param name="pt2"></param>
        /// <returns></returns>
        public static double SquareDistance(KdPoint pt1, KdPoint pt2)
        {
            if (pt1 == null || pt2 == null) return double.NaN;

            int k = Math.Min(pt1.NumDimensions, pt2.NumDimensions);

            double dist = 0;

            for (int i = 0; i < k; i++)
            {
                double d = pt1[i] - pt2[i];
                dist += d * d;
            }

            return dist;

        }


        public object Clone()
        {
            return MemberwiseClone();
        }



    }
}
